package com.web;

import lombok.SneakyThrows;
import org.apache.http.Header;
import org.apache.http.NameValuePair;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Response;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.ContentType;
import org.apache.http.message.BasicNameValuePair;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * @author：zhang guoxiang
 * @date：2022/4/15
 */
public abstract class HttpClientUtils {

    /**
     * 发送get请求
     */
    public static class Get {

        /**
         * @param url 请求路径
         */
        @SneakyThrows
        public static Response get(String url) {
            return Request.Get(url)
                    .execute();
        }

        /**
         * @param url    请求路径
         * @param params 请求参数
         */
        @SneakyThrows
        public static Response get(String url, Map<String, Object> params) {
            return Request.Get(encodeUrl(url, nameValuePairs(params)))
                    .execute();
        }

        private static String encodeUrl(String url, List<? extends NameValuePair> nameValues) {
            String format = URLEncodedUtils.format(nameValues, UTF_8.displayName());
            return format.isEmpty() ? url : String.format("%s?%s", url, format);
        }
    }

    private static List<? extends NameValuePair> nameValuePairs(Map<String, Object> map) {
        return map.entrySet().stream().filter(entry -> entry.getValue() != null).map(entry -> {
            String entryKey = entry.getKey();
            String entryValue = entry.getValue().toString();
            return new BasicNameValuePair(entryKey, entryValue);
        }).collect(Collectors.toList());
    }

    /**
     * 发送post请求
     */
    public static class Post {

        /**
         * @param url 请求路径
         */
        @SneakyThrows
        public static Response post(String url) {
            return Request.Post(url)
                    .execute();
        }

        /**
         * @param url  请求路径
         * @param body 请求体内容
         */
        @SneakyThrows
        public static Response post(String url, Map<String, Object> body) {
            return Request.Post(url)
                    .bodyForm(nameValuePairs(body))
                    .execute();
        }

        /**
         * @param url  请求路径
         * @param body 请求体内容
         */
        @SneakyThrows
        public static Response post(String url, List<? extends NameValuePair> body) {
            return Request.Post(url)
                    .bodyForm(body)
                    .execute();
        }

        /**
         * @param url     请求路径
         * @param body    请求体内容
         * @param headers 请求头
         */
        @SneakyThrows
        public static Response post(String url, List<? extends NameValuePair> body, Header... headers) {
            return Request.Post(url)
                    .setHeaders(headers)
                    .bodyForm(body)
                    .execute();
        }

        /**
         * @param url      请求路径
         * @param jsonBody json请求体内容
         */
        @SneakyThrows
        public static Response post(String url, String jsonBody) {
            return Request.Post(url)
                    .bodyString(jsonBody, ContentType.APPLICATION_JSON)
                    .execute();
        }

        /**
         * @param url      路径
         * @param jsonBody 请求体
         * @param headers  请求头
         */
        @SneakyThrows
        public static Response post(String url, String jsonBody, Header... headers) {
            return Request.Post(url)
                    .setHeaders(headers)
                    .bodyString(jsonBody, ContentType.APPLICATION_JSON)
                    .execute();
        }
    }

    /**
     * 发送delete请求
     */
    public static class Delete {

        /**
         * @param url 请求路径
         */
        @SneakyThrows
        public static Response delete(String url) {
            return Request.Delete(url)
                    .execute();
        }

        /**
         * @param url     请求路径
         * @param headers 请求头
         */
        @SneakyThrows
        public static Response delete(String url, Header... headers) {
            return Request.Delete(url)
                    .setHeaders(headers)
                    .execute();
        }

        /**
         * @param url      请求路径
         * @param jsonBody 请求体数据(json)
         * @param headers  请求头
         */
        @SneakyThrows
        public static Response delete(String url, String jsonBody, Header... headers) {
            return Request.Delete(url)
                    .setHeaders(headers)
                    .bodyString(jsonBody, ContentType.APPLICATION_JSON)
                    .execute();
        }

        /**
         * @param url      请求路径
         * @param jsonBody 请求体数据（json）
         */
        @SneakyThrows
        public static Response delete(String url, String jsonBody) {
            return Request.Delete(url)
                    .bodyString(jsonBody, ContentType.APPLICATION_JSON)
                    .execute();
        }
    }

    /**
     * 发送put请求
     */
    public static class Put {


        /**
         * @param url 请求路径
         */
        @SneakyThrows
        public static Response put(String url) {
            return Request.Put(url)
                    .execute();
        }

        /**
         * @param url     请求路径
         * @param headers 请求头
         */
        @SneakyThrows
        public static Response put(String url, Header... headers) {
            return Request.Put(url)
                    .setHeaders(headers)
                    .execute();
        }

        /**
         * @param url      请求路径
         * @param jsonBody 请求体数据（json）
         * @param headers  请求头
         */
        @SneakyThrows
        public static Response put(String url, String jsonBody, Header... headers) {
            return Request.Put(url)
                    .setHeaders(headers)
                    .bodyString(jsonBody, ContentType.APPLICATION_JSON)
                    .execute();
        }

        /**
         * @param url      请求路径
         * @param jsonBody 请求体数据（json）
         */
        @SneakyThrows
        public static Response put(String url, String jsonBody) {
            return Request.Put(url)
                    .bodyString(jsonBody, ContentType.APPLICATION_JSON)
                    .execute();
        }

        /**
         * @param url     请求路径
         * @param body    请求体内容
         * @param headers 请求头
         */
        @SneakyThrows
        public static Response put(String url, List<? extends NameValuePair> body, Header... headers) {
            return Request.Post(url)
                    .setHeaders(headers)
                    .bodyForm(body)
                    .execute();
        }

    }
}
